package cn.com.b2office.dao.hibernate;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import cn.com.b2office.dao.OrderDao;
import cn.com.b2office.domain.AccountActivity;
import cn.com.b2office.domain.ExData;
import cn.com.b2office.domain.Order;
import cn.com.b2office.domain.OrderItem;
import cn.com.b2office.domain.Sequence;
import cn.com.b2office.exchange.ClassMapping;

public class OrderDaoHibernateImpl extends HibernateDaoSupport implements
		OrderDao {

	private static final String ORDER_SEQUENCE_NAME = "ORDER";

	private static final String ORDER_ITEM_SEQUENCE_NAME = "ORDER_ITEM";

	private static final Log logger = LogFactory
			.getLog(OrderDaoHibernateImpl.class);

	private SimpleDateFormat df = new SimpleDateFormat("yyMMdd");

	public void createOrder(Order order) {
		Session s = getSession();
		try {
			s.save(order);
			// trigger
			ExData data = new ExData();
			data.setEntity(ClassMapping.getClassCode(Order.class));
			data.setEntityId(order.getOrderId());
			data.setOperation(ExData.INSERT);
			data.setModifytime(new Date());
			s.save(data);
			s.flush();
		} catch (RuntimeException e) {
			throw e;
		} finally {
			releaseSession(s);
		}
	}

	@SuppressWarnings("unchecked")
	public List<OrderItem> findOrderItems(String orderId) {
		return getHibernateTemplate().find(
				"from OrderItem where orderId='" + orderId + "'");
	}

	@SuppressWarnings("unchecked")
	public List<Order> findOrders(String memberId, int firstResult,
			int maxResults) {
		List<Order> orders = null;
		Session s = getSession();
		try {
			orders = s
					.createQuery(
							"from Order where memberId=:memberId order by orderDate desc")
					.setString("memberId", memberId)
					.setFirstResult(firstResult).setMaxResults(maxResults)
					.list();
		} catch (HibernateException e) {
			throw e;
		} finally {
			releaseSession(s);
		}
		return orders;
	}

	@SuppressWarnings("unchecked")
	public List<Order> findOrders(String memberId, int orderStatus,
			int firstResult, int maxResults) {
		Session session = getSession();
		List<Order> listOrders = null;
		try {
			if (orderStatus == 5) { // orderStatus 状态为5即查询所有状态信息
				listOrders = session.createQuery(
						"from Order where memberId=" + "'" + memberId
								+ "' order by orderDate desc").setFirstResult(
						firstResult).setMaxResults(maxResults).list();
			} else {
				listOrders = session.createQuery(
						"from Order where memberId=" + "'" + memberId + "'"
								+ " and orderStatus=" + orderStatus
								+ " order by orderDate desc").setFirstResult(
						firstResult).setMaxResults(maxResults).list();
			}
		} catch (RuntimeException e) {
			throw e;
		} finally {
			releaseSession(session);
		}
		return listOrders;
	}

	public synchronized String createOrderId() {
		int id = 0;
		Session s = getSession();
		try {
			Sequence sequence = (Sequence) s.get(Sequence.class,
					ORDER_SEQUENCE_NAME);
			if (sequence == null) {
				sequence = new Sequence();
				sequence.setName(ORDER_SEQUENCE_NAME);
				sequence.setNextId(1);
				s.save(sequence);
				s.flush();
			}
			id = sequence.getNextId();
			// 自增
			sequence.setNextId(id + 1);
			s.save(sequence);
			s.flush();
		} catch (RuntimeException e) {
			logger.error(e.getMessage());
			throw e;
		} finally {
			releaseSession(s);
		}
		return "W" + df.format(new Date()) + buildStr(id, 4);
	}

	private String buildStr(int num, int length) {
		String str = String.valueOf(num);
		int strLength = str.length();
		if (strLength >= length)
			return str;
		StringBuilder sb = new StringBuilder();

		for (int i = 0; i < length - strLength; i++) {
			sb.append("0");
		}
		sb.append(str);
		return sb.toString();
	}

	public void createOrderItem(OrderItem orderItem) {
		if (orderItem.getOrderItemId() == null)
			throw new RuntimeException("orderItem's Id not assigned.");
		Session s = getSession();
		try {
			s.save(orderItem);
			// trigger
			ExData data = new ExData();
			data.setEntity(ClassMapping.getClassCode(OrderItem.class));
			data.setEntityId(orderItem.getOrderItemId());
			data.setOperation(ExData.INSERT);
			data.setModifytime(new Date());
			s.save(data);
			s.flush();
		} catch (RuntimeException e) {
			throw e;
		} finally {
			releaseSession(s);
		}
	}

	public synchronized String createOrderItemId() {
		int id = 0;
		Session s = getSession();
		try {
			Sequence sequence = (Sequence) s.get(Sequence.class,
					ORDER_ITEM_SEQUENCE_NAME);
			if (sequence == null) {
				sequence = new Sequence();
				sequence.setName(ORDER_ITEM_SEQUENCE_NAME);
				sequence.setNextId(1);
				s.save(sequence);
				s.flush();
			}
			id = sequence.getNextId();
			// 自增
			sequence.setNextId(id + 1);
			s.save(sequence);
			s.flush();
		} catch (RuntimeException e) {
			logger.error(e.getMessage());
			throw e;
		} finally {
			releaseSession(s);
		}
		return "W" + df.format(new Date()) + buildStr(id, 5);
	}

	public synchronized List<String> createOrderItemId(int num) {
		int id = 0;
		Session s = getSession();
		try {
			Sequence sequence = (Sequence) s.get(Sequence.class,
					ORDER_ITEM_SEQUENCE_NAME);
			if (sequence == null) {
				sequence = new Sequence();
				sequence.setName(ORDER_ITEM_SEQUENCE_NAME);
				sequence.setNextId(1);
				s.save(sequence);
				s.flush();
			}
			id = sequence.getNextId();
			// 自增
			sequence.setNextId(id + num);
			s.save(sequence);
			s.flush();
		} catch (RuntimeException e) {
			logger.error(e.getMessage());
			throw e;
		} finally {
			releaseSession(s);
		}
		String date = df.format(new Date());
		List<String> array = new ArrayList<String>(num);
		for (int i = 0; i < num; i++) {
			array.add("W" + date + buildStr(id++, 5));
		}
		return array;
	}

	public void createOrderItems(List<OrderItem> orderItems) {
		for (OrderItem orderItem : orderItems) {
			if (orderItem.getOrderItemId() == null)
				throw new RuntimeException("orderItem's Id not assigned.");
		}
		Session s = getSession();
		try {
			for (OrderItem orderItem : orderItems) {
				s.save(orderItem);
				// trigger
				ExData data = new ExData();
				data.setEntity(ClassMapping.getClassCode(OrderItem.class));
				data.setEntityId(orderItem.getOrderItemId());
				data.setOperation(ExData.INSERT);
				data.setModifytime(new Date());
				s.save(data);
			}
			s.flush();
		} catch (RuntimeException e) {
			logger.error("createOrderItems(..) error. " + e.getMessage());
			throw e;
		} finally {
			releaseSession(s);
		}
	}

	/**
	 * 获取用户的第一个有效订单（postatus!=-1 and cancelapp!=1）
	 * 
	 * @param memberid
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Order getFirstValidOrder(String memberid) {
		List<Order> orders = null;
		Session s = getSession();
		try {
			Criteria criteria = s.createCriteria(Order.class);
			criteria.add(Expression.eq("memberId", memberid));
			criteria.add(Expression.ne("orderStatus", -1));
			criteria.add(Expression.ne("cancelApp", 1));
			criteria.addOrder(org.hibernate.criterion.Order.asc("orderDate"));
			criteria.setFirstResult(0);
			criteria.setMaxResults(1);
			orders = criteria.list();
		} catch (RuntimeException e) {
			throw e;
		} finally {
			releaseSession(s);
		}
		if (orders != null && orders.size() == 1)
			return orders.get(0);
		return null;
	}

	public Order getOrder(String orderId) {
		return (Order) getHibernateTemplate().get(Order.class, orderId);
	}

	public void updateOrder(Order order) {
		Session s = getSession();
		try {
			s.update(order);
			// trigger
			ExData data = new ExData();
			data.setEntity(ClassMapping.getClassCode(Order.class));
			data.setEntityId(order.getOrderId());
			data.setOperation(ExData.UPDATE);
			data.setModifytime(new Date());
			s.save(data);
			s.flush();
		} catch (RuntimeException e) {
			throw e;
		} finally {
			releaseSession(s);
		}

	}

	/** 根据订单状态查询订单数 */
	public int getTotalRecordNumByOrderStatus(String memberId, int orderStatus) {
		List list = null;
		if (orderStatus == 5) {
			list = getHibernateTemplate().find(
					"select orderId from Order where memberId=?", memberId);
		} else {
			list = getHibernateTemplate()
					.find(
							"select orderId from Order where memberId=? and orderStatus=? ",
							new Object[] { memberId, orderStatus });
		}
		return list.size();
	}

}
